/************************************************************************
  DISCLAIMER:
  This software was produced by the National Institute of Standards
  and Technology (NIST), an agency of the U.S. government, and by statute
  is not subject to copyright in the United States.  Recipients of this
  software assume all responsibility associated with its operation,
  modification, maintenance, and subsequent redistribution.

  See NIST Administration Manual 4.09.07 b and Appendix I.
************************************************************************/

#include <stdio.h>   // for stderr, etc.
#include <string.h>  // for strcat, etc.
#include <stdlib.h>  // for exit

/********************************************************************/

void printConfAssignModule();
void printConfList(const char * prefix, const char * fileName, FILE * checker);

/********************************************************************/

/*

The work done here is generating the assignModuleSubAtts.cc file.
That functionality is not included in debnf2pars because it is necessary
to read the 27 xxLists.cc files in order to do the generation, and
those files are likely to be changed after debnf2pars runs.

*/

int main(       /* ARGUMENTS                                      */
 int argc,      /* one more than the number of command arguments  */
 char * argv[]) /* array of executable name and command arguments */
{
  printConfAssignModule();
  return 0;
}

/********************************************************************/

/* printConfAssignModule

Returned Value: none

Called By: main

This prints the assignModuleSubAtts.cc file that is #included in the
checker, the tester, and elsewhere. The file defines the
assignModuleSubAtts function. After printing the first two lines of
the assignModuleSubAtts function, this calls printConfList for each of
the 27 subsets of DMIS that is a level of an AP or a level of and
addendum in the DMIS conformance classes. Those functions each print a
set of lines. Each line in each set wires a named array of names (of
either subtypes or attributes) for each class in the set into a named
array of arrays of names. For example, the first four lines that are
printed into the assignModuleSubAtts function as a result of calling
printConfList("rt3", "source/rt3Lists.cc", checker) are:

rt3Lists[0] = rt3aclratAngSpecSubs;
rt3Lists[1] = rt3aclratAngularAtts;
rt3Lists[2] = rt3aclratMinorSubs;
rt3Lists[3] = rt3aclratRotAtts;

The 27 named arrays (p3Lists, rt3Lists, etc.) exist to make it easy to
combine the contents of several named lists in masterSubAtts.

*/

void printConfAssignModule() /*  NO ARGUMENTS       */
{
  FILE * lister;         // file to print to

  lister = fopen("assignModuleSubAtts.cc", "w");
  if (lister == 0)
  {
    fprintf(stderr, "Could not open source/assignModuleSubAtts.cc for writing. Are you in the correct directory?\n");
    exit(1);
  }
  fprintf(lister, "namespace NDTU {\n");
  fprintf(lister, "void assignModuleSubAtts()\n");
  fprintf(lister, "{\n");
  printConfList("cs1", "source/cs1Lists.cc", lister);
  printConfList("cs2", "source/cs2Lists.cc", lister);
  printConfList("cs3", "source/cs3Lists.cc", lister);
  printConfList("ipv1", "source/ipv1Lists.cc", lister);
  printConfList("ipv2", "source/ipv2Lists.cc", lister);
  printConfList("ipv3", "source/ipv3Lists.cc", lister);
  printConfList("mc1", "source/mc1Lists.cc", lister);
  printConfList("mc2", "source/mc2Lists.cc", lister);
  printConfList("mc3", "source/mc3Lists.cc", lister);
  printConfList("p1", "source/p1Lists.cc", lister);
  printConfList("p2", "source/p2Lists.cc", lister);
  printConfList("p3", "source/p3Lists.cc", lister);
  printConfList("qis1", "source/qis1Lists.cc", lister);
  printConfList("qis2", "source/qis2Lists.cc", lister);
  printConfList("qis3", "source/qis3Lists.cc", lister);
  printConfList("rt1", "source/rt1Lists.cc", lister);
  printConfList("rt2", "source/rt2Lists.cc", lister);
  printConfList("rt3", "source/rt3Lists.cc", lister);
  printConfList("sga1", "source/sga1Lists.cc", lister);
  printConfList("sga2", "source/sga2Lists.cc", lister);
  printConfList("sga3", "source/sga3Lists.cc", lister);
  printConfList("tw1", "source/tw1Lists.cc", lister);
  printConfList("tw2", "source/tw2Lists.cc", lister);
  printConfList("tw3", "source/tw3Lists.cc", lister);
  printConfList("unc1", "source/unc1Lists.cc", lister);
  printConfList("unc2", "source/unc2Lists.cc", lister);
  printConfList("unc3", "source/unc3Lists.cc", lister);
  fprintf(lister, "}\n");
  fprintf(lister, "} // namespace NDTU\n");
  fclose(lister);
}

/********************************************************************/

/* printConfList

Returned Value: none

Called By: printConfAssignModule

This function expects the input file to be in a specific format.
Any start comment or end comment symbols in the file must occur at
the beginning of a line.

This skips all comment lines. On non-comment lines, it looks for
"const char * ". That string is always followed by a name followed by
[]. Whenever a line of that form is found, this function prints:
     <prefix>Lists[<n>] = name;
where n is incremented by 1 each time a line is printed.

See documentation of printConfAssignModule.

*/

void printConfList(     /*  ARGUMENTS            */
 const char * prefix,   /* prefix for array name */
 const char * fileName, /* name of file to read  */
 FILE * checker)        /* file to print to      */
{
  FILE * inFile;
  static char line[200];
  int comment;
  int n;
  int k;

  inFile = fopen(fileName, "r");
  if (inFile == 0)
    {
      fprintf(stderr, "could not open %s for reading\n", fileName);
      exit(1);
    }
  fgets(line, 199, inFile);
  fgets(line, 199, inFile);
  comment = 0;
  n = 0;
  while (fgets(line, 199, inFile))
    {
      if (comment)
	{
	  if ((line[0] == '*') && (line[1] == '/'))
	    comment = 0;
	}
      else if ((line[0] == '/') && (line[1] == '*'))
	comment = 1;
      else if (strncmp(line, "const char * ", 13) == 0)
	{
	  fprintf(checker, "%sLists[%d] = ", prefix, n++);
	  for (k = 13; line[k] != '['; k++)
	    fputc(line[k], checker);
	  fprintf(checker, ";\n");
	}
    }
  fprintf(checker, "%sLists[%d] = 0;\n\n", prefix, n);
  fclose(inFile);
}

/********************************************************************/

